// 树转列表
export function treeToArray<T extends any[]>(tree: any[], key = 'children'): T {
  return tree.reduce(function merge(con, item) {
    con.push(item);
    if (item[key] && item[key].length > 0) {
      item[key].reduce(merge, con);
    }
    return con;
  }, []);
}

// 列表转树
export function arrayToTree<T extends any[]>(arr: any[], key: string, parentKey = 'parentId'): T {
  // 创建节点映射
  const map: any = {};
  arr.forEach((item) => {
    map[item[key]] = { ...item, children: undefined };
  });
  // 构建树结构
  const result: any[] = [];
  arr.forEach((item) => {
    if (item[parentKey] == 0) {
      result.push(map[item[key]]);
    } else {
      if (!map[item[parentKey]].children) map[item[parentKey]].children = [];
      map[item[parentKey]].children.push(map[item[key]]);
    }
  });
  return result as T;
}

// 列表转对象
export function arrayToObject<T extends object>(arr: any[], key: string, value: string): T {
  const data: any = {};
  arr.forEach((item) => {
    data[`${item[key]}`] = item[value];
  });
  return data as T;
}

// 数组去重
export function arrayDistinct<T extends any[]>(arr: any[], iteratee?: Function | string): T {
  if (!iteratee) {
    return [...new Set(arr)] as T;
  }
  const hash: string[] = [];
  return arr.filter((item) => {
    const key = typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
    return !hash.includes(key) && !!hash.push(key);
  }) as T;
}

// 数组分组
export function arrayGroupBy<T extends any[]>(arr: any[], iteratee: Function | string): T {
  const list: any[] = [];
  for (const item of arr) {
    const groupKey = typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
    const index = list.findIndex((item) => JSON.stringify(item.key)  === JSON.stringify(groupKey));
    if (index == -1) {
      list.push({ key: groupKey, value: [item] });
    } else {
      list[index].value.push(item);
    }
  }
  return list as T;
}

// 多维数组扁平化
export function arrayFlatten<T extends any[]>(arr: any[], deep: number): T {
  const result: any[] = [];
  const flatten = (currentArr: any[], currentDeep: number) => {
    for (const item of currentArr) {
      if (Array.isArray(item) && currentDeep > 0) {
        flatten(item, currentDeep - 1);
      } else {
        result.push(item);
      }
    }
  };
  flatten(arr, deep || Infinity);
  return result as T;
}

// 一维数组二维化
export function arrayNested<T extends any[]>(arr: any[], size: number | Function): T {
  let index = 0;
  let currentIndex = 0;
  const result: any[] = [];
  while (currentIndex < arr.length) {
    const element = arr[currentIndex];
    const actualSize = typeof size === 'function' ? size(element, index, currentIndex) : size;
    const chunk = arr.slice(currentIndex, currentIndex + actualSize);
    result.push(chunk);
    currentIndex += actualSize;
    index++;
  }
  return result as T;
}

// 数组默认同上效果
export function arraySameAbove<T extends any[]>(arr: any[], props: string | string[]): T {
  if (typeof props == 'string') {
    props = props.split(',');
  }
  for (let i = 0; i < props.length; i++) {
    const key = props[i];
    let above: any;
    arr.forEach((item) => {
      if (item[key]) {
        above = item[key];
      } else if (above) {
        item[key] = above;
      }
    });
  }
  return arr as T;
}

// 排除数组中指定的值
export function arrayDifference<T extends any[]>(arr: any[], values: string | string[]): T {
  if (typeof values == 'string') {
    values = values.split(',');
  }
  return arr.filter((t) => !values.includes(t)) as T;
}

// 计算树形结构复选框状态
export function calculateTreeState(tree: any[], keys = 'children'): any[] {
  const calculateNodeTreeState = function (nodes: any[], keys: string) {
    let allChecked = true;
    let someChecked = false;
    for (const node of nodes) {
      const hasChildren = keys.split(',').some((k: string) => node[k] && node[k].length > 0);
      if (hasChildren) {
        // 递归计算子节点状态
        let children: any[] = [];
        keys.split(',').forEach((k) => {
          if (node[k] && node[k].length > 0) children = node[k];
        });
        const childState = calculateNodeTreeState(children, keys);
        // 更新节点的计算状态
        node.checkAll = childState.checkAll;
        node.indeterminate = childState.indeterminate;
        // 根据子节点状态更新当前层级状态
        if (childState.checkAll) {
          someChecked = true;
        } else if (childState.indeterminate) {
          someChecked = true;
          allChecked = false;
        } else {
          allChecked = false;
        }
      } else {
        // 叶子节点的处理
        if (node.checked) {
          someChecked = true;
        } else {
          allChecked = false;
        }
      }
    }
    return {
      checkAll: allChecked,
      indeterminate: someChecked && !allChecked,
    };
  };
  calculateNodeTreeState(tree, keys);
  return tree;
}

// 树形结构复选框状态更新
export function updateTreeState(tree: any[], state: boolean, keys = 'children'): any[] {
  const updateNodeTreeState = function (nodes: any[], state: boolean, keys: string) {
    for (const node of nodes) {
      const hasChildren = keys.split(',').some((k: string) => node[k] && node[k].length > 0);
      if (hasChildren) {
        // 递归计算子节点状态
        let children: any[] = [];
        keys.split(',').forEach((k) => {
          if (node[k] && node[k].length > 0) children = node[k];
        });
        updateNodeTreeState(children, state, keys);
      } else {
        node.checked = state;
      }
    }
  };
  updateNodeTreeState(tree, state, keys);
  return tree;
}

// 获取树形结构复选框选中
export function getTreeChecked(tree: any[], keys = 'children'): any[] {
  let result: any[] = [];
  for (const node of tree) {
    const hasChildren = keys.split(',').some((k: string) => node[k] && node[k].length > 0);
    if (hasChildren) {
      // 递归计算子节点状态
      let children: any[] = [];
      keys.split(',').forEach((k) => {
        if (node[k] && node[k].length > 0) children = node[k];
      });
      const arr = getTreeChecked(children, keys);
      result = [...result, ...arr];
    } else if (node.checked) {
      result.push(node);
    }
  }
  return result;
}
